// This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
// IMPORTANT NOTES: 
// This sample can be run only on Windows XP.  The default Windows 2000 security policy 
// prevents this sample from executing properly, and changing the policy to allow
// proper execution presents a security risk. 

using System;
using System.Security.Permissions;
using System.Security.Principal;
using CSW.Framework.Windows.Win32API;

namespace CSW.Framework.Windows
{
    /// <summary>
    /// Used to impersonate another user on the network.
    /// </summary>
    public static class Impersonation
    {
        private static IntPtr tokenHandle;
        private static WindowsImpersonationContext impersonatedUser;

        /// <summary>
        /// Authenticates the specified user.
        /// </summary>
        /// <param name="domainName">Name of the domain.</param>
        /// <param name="userID">The user ID.</param>
        /// <param name="password">The password.</param>
        /// <returns><c>true</c> if successful; otherwise, <c>false</c>.</returns>
        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
        public static bool Authenticate(string domainName, string userID, string password)
        {
            //tokenHandle = new IntPtr(0);
            tokenHandle = IntPtr.Zero;

            // Call LogonUser to obtain a handle to an access token.
            Boolean returnValue = Win32.LogonUser(userID, domainName, password,
                                            Win32.LOGON32_LOGON_INTERACTIVE, Win32.LOGON32_PROVIDER_DEFAULT,
                                            ref tokenHandle);

            if (!returnValue)
                return false;

            // Use the token handle returned by LogonUser.
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);
            impersonatedUser = newId.Impersonate();

            return true;
        }

        /// <summary>
        /// Stop impersonating the user.
        /// </summary>
        public static void Reset()
        {
            impersonatedUser.Undo();

            // Free the tokens.
            if (tokenHandle != IntPtr.Zero) 
                Win32.CloseHandle(tokenHandle);
        }
    }
}